package ru.eas.graph;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class StrongConnectedComponent {

    public static void main(String[] args) {
        String testString = "4 4\n" +
                "1 2\n" +
                "4 1\n" +
                "2 3\n" +
                "3 1";
        Scanner scanner = new Scanner(testString);

//        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        DirectedGraph graph = new DirectedGraph(n);
        for (int i = 0; i < m; i++) {
            graph.addEdge(scanner.nextInt(), scanner.nextInt());
        }
        System.out.println(graph.strongConnectedComponentCount());
    }

    static class DirectedGraph {

        private List<List<Integer>> vertices;
        private boolean[] visited;
        private int strongConnectedComponentsCount;
        private List<Integer> endOrderedVertices;

        public DirectedGraph(int vertexCount) {
            vertexCount++;
            vertices = new ArrayList<List<Integer>>(vertexCount);
            for (int i = 0; i < vertexCount; i++) {
                vertices.add(new ArrayList<Integer>());
            }
            visited = new boolean[vertexCount];
            endOrderedVertices = new ArrayList<Integer>();
        }

        public void addEdge(int vertex1, int vertex2) {
            vertices.get(vertex1).add(vertex2);
        }

        private void clearVisited() {
            for (int i = 0; i < visited.length; i++) {
                visited[i] = false;
            }
        }

        private void dfs() {
            clearVisited();
            for (int i = 1; i < vertices.size(); i++) {
                if (visited[i] == false) {
                    explore(i);
                }
            }
        }

        private void dfs(List<Integer> vertices) {
            clearVisited();
            for (int i = vertices.size() - 1; i >= 0 ; i--) {
                int vertex = vertices.get(i);
                if (visited[vertex] == false) {
                    strongConnectedComponentsCount++;
                    explore(vertex);
                }
            }
        }

        public void explore(int vertex) {
            visited[vertex] = true;
            for (int v : vertices.get(vertex)) {
                if (visited[v] == false) {
                    explore(v);
                }
            }
            endOrderedVertices.add(vertex);
        }

        public int strongConnectedComponentCount() {
            DirectedGraph reverseGraph = reverseGraph();
            reverseGraph.dfs();
            strongConnectedComponentsCount = 0;
            dfs(reverseGraph.endOrderedVertices);
            return strongConnectedComponentsCount;
        }

        public DirectedGraph reverseGraph() {
            DirectedGraph result = new DirectedGraph(vertices.size() - 1);
            for (int vertex1 = 1; vertex1 < vertices.size(); vertex1++) {
                for (int vertex2 : vertices.get(vertex1)) {
                    result.addEdge(vertex2, vertex1);
                }
            }
            return result;
        }
    }
}
